#pragma once

/********************************************************************
	Module    :
	Filename  : 	e:\Application\GuiDll\GuiSrc\Control\container.h
	Author    :		Leon
	Version   :		1.01
	Date      :		9:10:2008   19:26
	Function  :
    Remark    :

    Modify history:
======================================================================
    Date      :
    Modifier  :
    Item      :
======================================================================


*********************************************************************/

#include "../Gui.h"
#include "Misc.h"
#include "Gdi.h"

class CControl;
class CContainerPainter;

/**
*@brief The base container,normally one screen corresponding one container
*
*/

class GUI_API CContainer
{
public:
	/**
	*@param[in] hWnd Specifies the message received window
	*/
	CContainer(HWND hWnd);
	virtual ~CContainer(void);

public:
	/**
	*@brief Remove the control form the container by the id
	*@param[in] nID       The ID of the control id to be removed
	*@return  No return value
	*/
	void       RemoveControl(int nID);

	/**
	*@brief Remove all the controls form the container
	*@return  No return value
	*/
	void       RemoveAllControls();

	/**
	*@brief Add the Specified control to the container
	*@param[in] pControl  the destination control pointer
	*@return  The added control pointer
	*/
	CControl*  AddControl(CControl* pControl);

	/**
	*@brief Get the control pointer by the control ID
	*@param[in] nID  the destination control ID
	*@return  The control pointer
	*/
	CControl*  ControlFromID(int nID);

	/**
	*@brief Get the control pointer by the point
	*@param[in] pPoint  the destination point
	*@return  The control pointer
	*/
	CControl*  ControlFromPoint(CPoint pPoint);

	/**
	*@brief Get the control pointer by the index
	*@param[in] nIndex  the index of the control
	*@return  The control pointer
	*/
	CControl*  GetControl(int nIndex);

	//CControl*  HitTest(CPoint pPoint);

	/**
	*@brief Get the hot control 
	*@return  The hot control pointer
	*/
	CControl*  GetHotControl();

	/**
	*@brief Get the selected control 
	*@return  The selected control pointer
	*/
	CControl*  GetSelectedControl();

	/**
	*@brief Set the ContainerPainter
	*@param[in] pPainter The new  container painter
	*@return  No return value
	*/
	void	   SetPainter(CContainerPainter* pPainter);

	/**
	*@brief Specifies the new hot control
	*@param[in] pItem The new selected control
	*@return  No return value
	*/
	void	   SelectControl(CControl* pItem);

	/**
	*@brief Get the control position and size
	*@return  The control rect
	*/
	CRect      GetControlRect();

	/**
	*@brief   Get the control total number
	*@return  The control count
	*/
	int        GetControlCount();

	/**
	*@brief   Get the container painter
	*@return  The painter
	*/
	inline 	CContainerPainter* GetPainter()
	{
		return m_pPainter;
	}

	/**
	*@brief    Specifies the container new background
	*@param[in]    pBackgnd The background bitmap file handle
	*@return   No return value
	*/
	void SetBackGnd(HBITMAP  pBackgnd)
	{
		if(m_hBmpBackgnd && pBackgnd)
		{
			DeleteObject(m_hBmpBackgnd);
		}
		m_hBmpBackgnd = pBackgnd;
	}

	/**
	*@brief    Get the container background 
	*@return   The background bitmap file handle
	*/
	inline HBITMAP  GetBackGnd()
	{
		return m_hBmpBackgnd;
	}

	/**
	*@brief    Specifies the container new back color
	*@param[in]    clr The new back color for the container
	*@return   No return value
	*@warning  The back ground color of the container only effects when the background bitmap handle is NULL or invalidate
	*/
	inline void SetBackColor(COLORREF clr)
	{
		m_clrBK = clr;
	}

	/**
	*@brief    Get the container back color 
	*@return   The back color of the container
	*/
	inline COLORREF GetBackColor()
	{
		return m_clrBK;
	}

	/**
	*@brief    Set the container position
	*@param    THe container rect
	*@return   The back color of the container
	*/
	inline void SetRect(CRect rcRect)
	{
		m_rcRect = rcRect;
	}

	/**
	*@brief    Get the container position
	*@return   The container rect
	*/
	inline CRect& GetRect()
	{
		return m_rcRect;
	}

	/**
	*@brief Get the Animation type
	*@return  The animation type value
	*/
	int  GetAniType(){return m_nAniType;};

	/**
	*@brief Get the exit Animation type
	*@return  The exit animation type value
	*/
	int  GetExitAniType(){return m_nExitAniType;};

	/**
	*@brief Get the Animation speed
	*@return  The animation speed value
	*/
	int  GetAniSpeed(){return m_nAniSpeed;};

	/**
	*@brief This function responses to process the message from the window. \n
	*@You have to overload this function if you want to process the message own in the container
	*@param[in] hWnd     The message origin window
	*@param[in] wMsg     Specifies the Windows message to be processed.
	*@param[in] wParam   Provides additional information used in processing the message. The parameter value depends on the message
	*@param[in] lParam   Provides additional information used in processing the message. The parameter value depends on the message
	*@return  No return value
	*/

	virtual void OnCommand(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam){};

	/**
	*@brief This function responses to initialize the container.\n
	*@You have to overload this function in the inherited class
	*@param[in]  hWnd   The message origin window
	*@retval     TRUE   Initialize the container success
	*@retval     FALSE  Initialize the container failed
	*/
	virtual BOOL InitControls(DWORD dwData){return TRUE;};


public:

	/**
	*@brief This function responses to handle the left button down message
	*@param[in]  nFlags   Unused in current version
	*@param[in]  point    Specifies the x- and y-coordinate of the cursor. These coordinates are always relative to the upper-left corner of the window
	*@return     No return value
	*/

	virtual void  OnLButtonDown(UINT nFlags, CPoint point);

	virtual void SetZoom(float fZoom);

	virtual float GetZoom();


	/**
	*@brief This function responses to handle the left button up message
	*@param[in]  nFlags   Unused in current version
	*@param[in]  point    Specifies the x- and y-coordinate of the cursor. These coordinates are always relative to the upper-left corner of the window
	*@return     No return value
	*/
	virtual void  OnLButtonUp(UINT nFlags, CPoint point);

	virtual	void  OnMouseMove(UINT nFlags, CPoint point);

	/**
	*@brief This function call the container's painter to draw the container
	*@param[in] pDC  To issue the flicker problem,you have to pass a temporary DC
	*@see CDC, CClientDC,CWindowDC,CContainerPainter::Paint(CDC* pDc, CContainer* pContainer, CRect& rc)
	*@return  No return value
	*/
	virtual void  OnPaint(CDC *pDC);
	/** 
	 *@see OnPaint
	*/
	virtual void  Paint(CDC *pDC);


	/** 
	*@ zxj update for sometimes will only refresh background
	*/
	virtual void  PaintBackGround( HDC hdc,LPRECT prc );

//protected:
//	void SetHotControl(CControl* pItem);
//	void Navigate(UINT nDirection);

public:
	vector<CControl*>   m_vecControls;
	HWND				m_hWnd;

protected:
	CContainerPainter*	m_pPainter;
	CControl*			m_pHotControl;    
	CControl*			m_pLastHotControl;
	COLORREF			m_clrBK;
	HBITMAP				m_hBmpBackgnd;
	CRect				m_rcRect;
	int	              m_nIndex;
	int					m_nAniType;
	int					m_nExitAniType;
	int					m_nAniSpeed;
	float               m_fZoom;
	friend class CControl;
	friend class CContainerPainter;
};
